# from cmcc import parse_html
import asyncio
import json
import time
from datetime import timedelta

import aioredis
import motor
from tornado import gen

from baseHandler import init_logger
from util.cmcc_10086 import cmcc10086_qrcode


async def pre_order(obj, conn, supplier, amount):
    user_data = await conn.rpop("cmcc_user", encoding='utf-8')
    if user_data:
        username, passwd, use_time = user_data.split("|")
    else:
        return None
    if float(use_time) > time.time():
        await conn.lpush("cmcc_user", user_data)

    if not obj:
        return None
    obj = json.loads(obj[1].replace("'", '"'))
    print(obj)
    if time.time() - obj["time"] > 30:
        # if time.time() - obj['time'] < 60:
        await db.rechange.update_one({"ordernumber": obj["ordernumber"]},
                                     {"$set": {
                                         "orderstate": "1"
                                     }})
        return
    await db.rechange.update_one({"ordernumber": obj["ordernumber"]},
                                 {"$set": {
                                     "orderstate": "8"
                                 }})

    try:
        pay_channel = "WX"
        try:
            future = cmcc10086_qrcode(obj["tel_number"], obj['amount'], conn, pay_channel, username,
                                      passwd)
            result = await asyncio.wait_for(future, timeout=60)
        except asyncio.TimeoutError:
            result = {"code": '2', "message": "超时"}

        wx_url = result.get('qrcode')
        order_url = result.get('url')
        order_id = result.get('orderid')
        message = result.get("message")
        logger.info("%s|%s", obj['ordernumber'], message)
        if result['code'] == "511004":
            use_time = time.time() + 30 * 60
            user_data = "%s|%s|%s" % (username, passwd, use_time)
            await conn.lpush('cmcc_user', user_data)
        elif result['code'] == "511005":
            logger.info("下单超限")
        else:
            user_data = "%s|%s|%s" % (username, passwd, use_time)
            await conn.lpush('cmcc_user', user_data)

        if wx_url:
            pre_queue_name = "PRE_CMCC_%s_%s" % (supplier, amount)
            obj.update(result)
            obj['userdata'] = user_data
            logger.info(pre_queue_name)

            await db.rechange.update_one({"ordernumber": obj["ordernumber"]},
                                                 {"$set": {'order_url': order_url,
                                                           'wx_url': wx_url,
                                                           "orderstate": '8',
                                                           "orderid": order_id,
                                                           "username": username
                                                           }
                                                  })
            await conn.lpush(pre_queue_name, json.dumps(obj))
        else:
            orderstate = '1'
            await db.rechange.update_one({"ordernumber": obj["ordernumber"]},
                                         {"$set": {"orderstate": orderstate, "message": message}})
    except Exception as e:
        logger.info("%s取单失败", obj["tel_number"])
        logger.error(e, exc_info=True)
        result = {"code": 2, 'message': "取单失败"}


async def periodic(supplier, amount):
    orderlist = await aioredis.create_redis(address=('localhost', 6379), loop=loop)
    task_queue = []
    while True:
        try:
            pre_queue_name = "PRE_CMCC_%s_%s" % (supplier, amount)
            pre_queue_size = await orderlist.llen(pre_queue_name)
            pre_cmcc_queue_len_name = "pre_cmcc_queue_len_%s_%s" % (supplier, amount)
            pre_size = await orderlist.get(pre_cmcc_queue_len_name, encoding='utf-8')
            if pre_size:
                pre_size = int(pre_size)
            else:
                pre_size = 3

            for i in task_queue:
                if i.done():
                    task_queue.remove(i)

            if len(task_queue) > 10:
                logger.info("任务过多")
                await  asyncio.sleep(1)
                continue

            logger.info("当前队列%s长度%s, 设置长度%s", pre_queue_name, pre_queue_size, pre_size)
            if pre_queue_size < pre_size:
                queue_name = "%s_%s" % (supplier, amount)
                obj = await orderlist.brpop(queue_name, encoding='utf-8')
                my_task = asyncio.Task(pre_order(obj, orderlist, supplier, amount))
                task_queue.append(my_task)
        except Exception as e:
            logger.info(e)
            await asyncio.sleep(5)
            continue
    else:
        orderlist.close()
        await orderlist.wait_closed()


if __name__ == '__main__':
    loop = asyncio.get_event_loop()

    logger = init_logger('cmcc', '/app/log/cs_notify/pre_order.log')

    supplier = 'M2018072714131532672011'
    task = asyncio.Task(periodic(supplier, '30'))
    task = asyncio.Task(periodic(supplier, '50'))
    task = asyncio.Task(periodic(supplier, '100'))
    client = motor.motor_tornado.MotorClient('mongodb://cs_user:cmcc5188@localhost:12018/cs_recharge')
    db = client.cs_recharge
    loop.run_forever()
